#ifndef RECTF_H_
#define RECTF_H_

#include <e32base.h>

class RectF
	{
public:
	float left;
	float top;
	float right;
	float bottom;

public:
	inline RectF() {}

	inline RectF(float left, float top, float right, float bottom)
		{
		this->left = left;
		this->top = top;
		this->right = right;
		this->bottom = bottom;
		}

	inline RectF(const RectF& r)
		{
		left = r.left;
		top = r.top;
		right = r.right;
		bottom = r.bottom;
		}

	inline RectF(const TRect& r)
		{
		left = r.iTl.iX;
		top = r.iTl.iY;
		right = r.iBr.iX;
		bottom = r.iBr.iY;
		}

	inline TBool IsEmpty()
		{
		return left >= right || top >= bottom;
		}

	inline float Width()
		{
		return right - left;
		}

	inline float Height()
		{
		return bottom - top;
		}

	inline float CenterX()
		{
		return (left + right) * 0.5f;
		}

	inline float CenterY()
		{
		return (top + bottom) * 0.5f;
		}

	inline void SetEmpty()
		{
		left = right = top = bottom = 0;
		}

	inline void Set(float left, float top, float right, float bottom)
		{
		this->left = left;
		this->top = top;
		this->right = right;
		this->bottom = bottom;
		}

	inline void Set(const RectF& src)
		{
		this->left = src.left;
		this->top = src.top;
		this->right = src.right;
		this->bottom = src.bottom;
		}

	inline void Set(const TRect& src)
		{
		this->left = src.iTl.iX;
		this->top = src.iTl.iY;
		this->right = src.iBr.iX;
		this->bottom = src.iBr.iY;
		}

	inline void Offset(float dx, float dy)
		{
		left += dx;
		top += dy;
		right += dx;
		bottom += dy;
		}

	inline void OffsetTo(float newLeft, float newTop)
		{
		right += newLeft - left;
		bottom += newTop - top;
		left = newLeft;
		top = newTop;
		}

	inline void Inset(float dx, float dy)
		{
		left += dx;
		top += dy;
		right -= dx;
		bottom -= dy;
		}

	inline TBool Contains(float x, float y)
		{
		return left < right && top < bottom // check for empty first
		&& x >= left && x < right && y >= top && y < bottom;
		}

	inline TBool Contains(float left, float top, float right, float bottom)
		{
		// check for empty first
		return this->left < this->right && this->top < this->bottom
		// now check for containment
		&& this->left <= left && this->top <= top
		&& this->right >= right && this->bottom >= bottom;
		}

	inline TBool Contains(const RectF& r)
		{
		// check for empty first
		return this->left < this->right && this->top < this->bottom
		// now check for containment
		&& left <= r.left && top <= r.top
		&& right >= r.right && bottom >= r.bottom;
		}

	inline TBool Intersect(float left, float top, float right, float bottom)
		{
		if (this->left < right && left < this->right
				&& this->top < bottom && top < this->bottom)
			{
			if (this->left < left)
				{
				this->left = left;
				}
			if (this->top < top)
				{
				this->top = top;
				}
			if (this->right > right)
				{
				this->right = right;
				}
			if (this->bottom > bottom)
				{
				this->bottom = bottom;
				}
			return true;
			}
		return false;
		}

	inline TBool Intersect(const RectF& r)
		{
		return Intersect(r.left, r.top, r.right, r.bottom);
		}

	inline TBool SetIntersect(const RectF& a, const RectF& b)
		{
		if (a.left < b.right && b.left < a.right
				&& a.top < b.bottom && b.top < a.bottom)
			{
			left = Max(a.left, b.left);
			top = Max(a.top, b.top);
			right = Min(a.right, b.right);
			bottom = Min(a.bottom, b.bottom);
			return true;
			}
		return false;
		}

	inline TBool Intersects(float left, float top, float right,
			float bottom)
		{
		return this->left < right && left < this->right
		&& this->top < bottom && top < this->bottom;
		}

	inline static TBool Intersects(const RectF& a, const RectF& b)
		{
		return a.left < b.right && b.left < a.right
		&& a.top < b.bottom && b.top < a.bottom;
		}

	inline void Union(float left, float top, float right, float bottom)
		{
		if ((left < right) && (top < bottom))
			{
			if ((this->left < this->right) && (this->top < this->bottom))
				{
				if (this->left > left)
				this->left = left;
				if (this->top > top)
				this->top = top;
				if (this->right < right)
				this->right = right;
				if (this->bottom < bottom)
				this->bottom = bottom;
				}
			else
				{
				this->left = left;
				this->top = top;
				this->right = right;
				this->bottom = bottom;
				}
			}
		}

	inline void Union(const RectF& r)
		{
		Union(r.left, r.top, r.right, r.bottom);
		}

	inline void Union(float x, float y)
		{
		if (x < left)
			{
			left = x;
			}
		else if (x > right)
			{
			right = x;
			}
		if (y < top)
			{
			top = y;
			}
		else if (y > bottom)
			{
			bottom = y;
			}
		}

	inline void Sort()
		{
		if (left > right)
			{
			float temp = left;
			left = right;
			right = temp;
			}
		if (top > bottom)
			{
			float temp = top;
			top = bottom;
			bottom = temp;
			}
		}
	};

#endif 
